package com.ahaoyou.listener;

import org.springframework.core.ResolvableType;

import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.concurrent.Executor;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class MyEventMulticaster {
    public Set<Listener<?>> listeners = new LinkedHashSet<>();

    private Executor taskExecutor;

    public MyEventMulticaster() {
        taskExecutor = new ThreadPoolExecutor(20, 100,
                60L, TimeUnit.SECONDS,
                new SynchronousQueue<Runnable>());
    }

    public Set<Listener<?>> getListeners(Event event) {
        Set<Listener<?>> listenerSet = new HashSet<>();
        for (Listener<?> listener : getListeners()) {
            //ResolvableType类来自spring中
            //获取到监听器中泛型
            ResolvableType listenerEventType = ResolvableType.forInstance(listener).as(Listener.class).getGeneric();
            //获取参数中类型
            ResolvableType eventType = ResolvableType.forInstance(event);
            //判断list中的泛型是否是参数或者参数的子类
            if (listenerEventType.isAssignableFrom(eventType)) {
                listenerSet.add(listener);
            }
            //获取事件接口类型
//            final Type[] type = listener.getClass().getGenericInterfaces();
//            for (Type tp : type) {
//                ParameterizedType pt = (ParameterizedType) tp;
//                //获取接口中的泛型
//                Type[] actualTypeArguments = pt.getActualTypeArguments();
//                //判断类型是否一致
//                if (actualTypeArguments[0].getTypeName().equals(event.getClass().getTypeName())) {
//                    listenerSet.add(listener);
//                }
//            }
        }
        return listenerSet;
    }

    public Set<Listener<?>> getListeners() {
        return listeners;
    }

    public void addListener(Listener<?> listener) {
        synchronized (listeners) {
            listeners.add(listener);
            System.out.println("新增了一个监听器：" + listener.getClass());
        }
    }

    public void removeListener(Listener<?> listener) {
        synchronized (listeners) {
            listeners.remove(listener);
            System.out.println("移除了一个监听器：" + listener.getClass());
        }
    }

    public void removeAllListener() {
        synchronized (listeners) {
            listeners.clear();
        }
    }

    public Executor getTaskExecutor() {
        return this.taskExecutor;
    }

    public void multicastEvent(final Event event) {
        Executor executor = getTaskExecutor();
        for (Listener<?> listener : getListeners(event)) {
            if (executor != null) {
                executor.execute(() -> invokeListener(listener, event));
            } else {
                invokeListener(listener, event);
            }
        }
    }

    protected void invokeListener(Listener<?> listener, Event event) {
        doInvokeListener(listener, event);
    }


    protected void doInvokeListener(Listener listener, Event event) {
        listener.onListEvent(event);
    }

}
